/**
 * 支付管理类
 * 统一管理支付流程、状态和错误处理
 */

import {
  PaymentStatus,
  PaymentError,
  checkWechatPayEnvironment,
  detectWechatAuthCallback,
  cachePaymentParams,
  getCachedPaymentParams,
  clearCachedPaymentParams,
  callWechatPay,
  getWechatAuth,
  createPaymentOrder,
  handlePaymentError,
  showPaymentLoading,
  hidePaymentLoading,
  showPaymentSuccess
} from './payment.js';

export class PaymentManager {
  constructor(options = {}) {
    this.contractNumber = options.contractNumber;
    this.contractData = options.contractData;
    this.status = PaymentStatus.IDLE;
    this.initialized = false; // 防止重复初始化
    this.isHandlingCallback = false; // 标记是否正在处理授权回调
    this.callbacks = {
      onStatusChange: options.onStatusChange || (() => {}),
      onSuccess: options.onSuccess || (() => {}),
      onError: options.onError || (() => {}),
      onCancel: options.onCancel || (() => {})
    };
  }

  /**
   * 设置状态
   * @param {string} status - 新状态
   */
  setStatus(status) {
    const oldStatus = this.status;
    this.status = status;
    this.callbacks.onStatusChange(status, oldStatus);
  }

  /**
   * 初始化支付管理器
   * @param {Object} pageOptions - 页面参数
   */
  async initialize(pageOptions = {}) {
    console.log('PaymentManager 初始化开始', pageOptions);
    
    // 防止重复初始化
    if (this.initialized) {
      console.log('PaymentManager 已初始化，跳过');
      return;
    }
    
    // 立即标记为已初始化，防止并发初始化
    this.initialized = true;
    
    try {
      // 检测微信授权回调
      const authResult = detectWechatAuthCallback(pageOptions);
      if (authResult.hasAuthCallback) {
        console.log('检测到授权回调，开始处理');
        // 先处理授权回调，再清理URL参数（在handleAuthCallback内部处理完后清理）
        await this.handleAuthCallback(authResult);
      } else if (authResult.isAlreadyProcessed) {
        // 清理URL中的授权参数，避免重复处理
        this.cleanupAuthParams();
      } else {
        console.log('非授权回调，检查缓存的支付参数');
        // 只在非授权回调时检查缓存
        await this.checkCachedPayment();
      }
    } catch (error) {
      console.error('初始化支付管理器失败:', error);
      // 确保在发生错误时重置处理标志
      this.isHandlingCallback = false;
      this.callbacks.onError(error);
    }
  }

  /**
   * 处理授权回调
   * @param {Object} authResult - 授权检测结果
   */
  async handleAuthCallback(authResult) {
    // 防止重复处理授权回调
    if (this.isHandlingCallback) {
      console.log('授权回调正在处理中，跳过重复请求');
      return;
    }
    
    // 立即设置处理标志，防止并发处理
    this.isHandlingCallback = true;
    console.log('开始处理微信授权回调:', authResult);
    
    // 先临时保存授权信息，防止处理过程中丢失（尽早保存，确保安全）
    const tempAuthKey = `temp_auth_${this.contractNumber}`;
    try {
      sessionStorage.setItem(tempAuthKey, JSON.stringify({
        authCode: authResult.authCode,
        authState: authResult.authState,
        timestamp: Date.now()
      }));
      console.log('临时保存授权信息成功:', authResult.authCode.substring(0, 6) + '...');
    } catch (e) {
      console.warn('临时保存授权信息失败:', e);
    }
    
    try {
      // 检查授权回调是否有效
      if (!authResult.hasAuthCallback || !this.isAuthCodeValid(authResult.authCode)) {
        console.warn('无效的授权回调或授权码:', authResult);
        throw new Error('无效的授权回调');
      }
    
      // 先检查是否已经处理过该授权回调，避免页面刷新后重复处理
      const processedKey = `auth_processed_${this.contractNumber || 'unknown'}_${authResult.authCode.substring(0, 10)}`;
      
      // 检查是否已经处理过该授权回调
      // 同时检查sessionStorage和localStorage，但优先使用sessionStorage
      let isProcessed = false;
      try {
        if (sessionStorage.getItem(processedKey)) {
          isProcessed = true;
        } else if (localStorage.getItem(processedKey)) {
          isProcessed = true;
        }
      } catch (e) {
        console.warn('检查授权回调处理状态失败:', e);
      }
      
      if (isProcessed) {
        console.log('授权回调已处理过，跳过重复处理');
        this.setStatus(PaymentStatus.IDLE);
        this.cleanupAuthParams();
        return;
      }
      
      this.setStatus(PaymentStatus.AUTHORIZING);
      
      // 显示授权成功提示
      uni.showToast({
        title: '授权成功，正在调起支付...',
        icon: 'success',
        duration: 2000
      });

      // 等待合同数据加载完成
      try {
        await this.waitForContractData();
        console.log('合同数据加载完成，准备创建支付订单');
      } catch (error) {
        console.error('合同数据加载失败:', error);
        // 即使合同数据加载失败，也尝试使用缓存的授权信息继续
        if (!this.contractData || !this.contractData.id) {
          throw new Error('合同数据加载失败，无法创建支付订单');
        }
      }

      // 优先使用临时存储中的授权信息，增强可靠性
      let finalAuthCode = authResult.authCode;
      let finalAuthState = authResult.authState;
      try {
        const tempAuthData = JSON.parse(sessionStorage.getItem(tempAuthKey) || '{}');
        if (tempAuthData.authCode && tempAuthData.authState && 
            this.isAuthCodeValid(tempAuthData.authCode) && 
            (Date.now() - tempAuthData.timestamp) < 60000) { // 60秒内有效
          finalAuthCode = tempAuthData.authCode;
          finalAuthState = tempAuthData.authState;
          console.log('使用临时存储中的授权信息');
        }
      } catch (e) {
        console.warn('获取临时存储的授权信息失败:', e);
      }

      // 再次检查授权码有效性
      if (!this.isAuthCodeValid(finalAuthCode)) {
        throw new Error('授权码无效或已过期');
      }

      // 直接使用授权码创建支付订单
      console.log('使用授权码创建支付订单:', { authCode: finalAuthCode.substring(0, 6) + '...', authState: finalAuthState });
      await this.processPaymentWithAuth(finalAuthCode, finalAuthState);
      
      // 授权回调处理成功后，标记为已处理
      sessionStorage.setItem(processedKey, 'true');
      console.log('授权回调处理成功并标记为已处理');
      
      // 同时在localStorage中也保存一份，增强可靠性
      try {
        localStorage.setItem(processedKey, 'true');
      } catch (e) {
        console.warn('无法在localStorage中保存处理状态:', e);
      }
      
      // 清除临时保存的授权信息
      try {
        sessionStorage.removeItem(tempAuthKey);
      } catch (e) {
        console.warn('无法清除临时授权信息:', e);
      }
      
      // 支付完成后清理URL参数
      this.cleanupAuthParams();
      
    } catch (error) {
      console.error('处理授权回调失败:', error);
      // 在授权回调处理失败时，不要重新触发支付流程
      // 只显示错误信息，让用户手动重试
      this.setStatus(PaymentStatus.FAILED);
      
      // 显示友好的错误提示
      uni.showToast({
        title: error.message || '支付授权失败，请重试',
        icon: 'none',
        duration: 2500
      });
      
      // 调用错误回调，但不清理状态
      if (this.callbacks.onError) {
        this.callbacks.onError(error);
      }
    } finally {
      this.isHandlingCallback = false; // 重置标志
    }
  }

  /**
   * 清理URL中的授权参数
   */
  cleanupAuthParams() {
    try {
      const url = new URL(window.location.href);
      const hasAuthParams = url.searchParams.has('code') || url.searchParams.has('state');
      
      if (hasAuthParams) {
        // 移除授权参数
        url.searchParams.delete('code');
        url.searchParams.delete('state');
        
        // 更新URL但不刷新页面
        window.history.replaceState({}, document.title, url.toString());
        console.log('已清理URL中的授权参数');
      }
    } catch (error) {
      console.error('清理URL参数失败:', error);
    }
  }

  /**
   * 检查缓存的支付参数
   */
  async checkCachedPayment() {
    const cachedParams = getCachedPaymentParams(this.contractNumber);
    
    if (cachedParams && cachedParams.wechat_pay_params) {
      // 询问用户是否继续支付
      const shouldContinue = await this.showContinuePaymentModal();
      
      if (shouldContinue) {
        await this.waitForContractData();
        await this.processPaymentWithCachedParams(cachedParams);
      } else {
        clearCachedPaymentParams(this.contractNumber);
      }
    }
  }

  /**
   * 显示继续支付的模态框
   * @returns {Promise<boolean>}
   */
  showContinuePaymentModal() {
    return new Promise((resolve) => {
      uni.showModal({
        title: '检测到未完成的支付',
        content: '检测到您有未完成的支付，是否继续支付？',
        confirmText: '继续支付',
        cancelText: '取消',
        success: (res) => {
          resolve(res.confirm);
        }
      });
    });
  }

  /**
   * 等待合同数据加载完成
   * @param {number} timeout - 超时时间（毫秒）
   */
  waitForContractData(timeout = 10000) {
    return new Promise((resolve, reject) => {
      if (this.contractData && this.contractData.id) {
        resolve();
        return;
      }

      const checkInterval = setInterval(() => {
        if (this.contractData && this.contractData.id) {
          clearInterval(checkInterval);
          resolve();
        }
      }, 500);

      setTimeout(() => {
        clearInterval(checkInterval);
        reject(new Error('合同数据加载超时'));
      }, timeout);
    });
  }

  /**
   * 使用缓存参数处理支付
   * @param {Object} cachedParams - 缓存的支付参数
   */
  async processPaymentWithCachedParams(cachedParams) {
    try {
      this.setStatus(PaymentStatus.PROCESSING);
      
      const result = await callWechatPay(
        cachedParams.wechat_pay_params,
        cachedParams.payment_type
      );
      
      this.handlePaymentSuccess(result);
      clearCachedPaymentParams(this.contractNumber);
    } catch (error) {
      this.handlePaymentError(error);
    }
  }

  /**
   * 使用授权码处理支付
   * @param {string} authCode - 授权码
   * @param {string} authState - 授权状态
   */
  async processPaymentWithAuth(authCode, authState) {
    try {
      this.setStatus(PaymentStatus.PROCESSING);
      showPaymentLoading('处理授权信息...');
      
      // 检查传入的授权信息是否有效
      let finalAuthCode = authCode;
      let finalAuthState = authState;
      
      // 尝试从临时存储中获取最新的授权信息（无论传入的是否有效）
      const tempAuthKey = `temp_auth_${this.contractNumber}`;
      try {
        const tempAuthData = JSON.parse(sessionStorage.getItem(tempAuthKey) || '{}');
        if (tempAuthData.authCode && tempAuthData.authState && 
            this.isAuthCodeValid(tempAuthData.authCode) && 
            (Date.now() - tempAuthData.timestamp) < 60000) { // 60秒内有效
          // 优先使用临时存储的授权信息，即使与传入的相同
          finalAuthCode = tempAuthData.authCode;
          finalAuthState = tempAuthData.authState;
          console.log('使用临时存储中的授权信息');
        }
      } catch (e) {
        console.warn('获取临时存储的授权信息失败:', e);
      }
      
      // 如果仍然没有有效授权码，报错
      if (!this.isAuthCodeValid(finalAuthCode)) {
        throw new Error('授权码无效或已过期');
      }
      
      console.log('使用授权码创建支付订单:', { authCode: finalAuthCode.substring(0, 6) + '...', authState: finalAuthState });

      // 创建支付订单，包含授权信息
      const paymentData = await createPaymentOrder({
        contractId: this.contractData.id,
        amount: this.contractData.payAmount,
        contractNumber: this.contractNumber,
        paymentMethod: 'wechat',
        authCode: finalAuthCode,
        authState: finalAuthState
      });

      hidePaymentLoading();
      console.log('授权支付订单创建完成，支付参数结构:', {
        hasAuthUrl: !!paymentData.auth_url,
        hasWechatPayParams: !!paymentData.wechat_pay_params,
        hasPaymentType: !!paymentData.payment_type,
        wechatPayParamsKeys: paymentData.wechat_pay_params ? Object.keys(paymentData.wechat_pay_params) : []
      });

      if (paymentData.auth_url) {
        // 服务器仍然返回授权URL，说明授权码可能无效或过期
        console.error('授权码验证失败，服务器要求重新授权');
        throw new Error('授权验证失败，请重新尝试支付');
      } else if (paymentData.wechat_pay_params && paymentData.payment_type) {
        console.log('开始调起微信支付（授权模式）');
        // 增加超时保护，确保支付调起不会无响应
        const payPromise = callWechatPay(
          {
            ...paymentData.wechat_pay_params,
            // 确保appId字段存在（微信SDK需要）
            appId: paymentData.wechat_pay_params.appId || (paymentData.appId || '')
          },
          paymentData.payment_type
        );
        
        // 设置超时处理
        const timeoutPromise = new Promise((_, reject) => {
          setTimeout(() => reject(new Error('支付调起超时')), 15000);
        });
        
        // 使用Promise.race来处理超时
        const result = await Promise.race([payPromise, timeoutPromise]);
        this.handlePaymentSuccess(result);
      } else {
        throw new Error('支付参数不完整: ' + JSON.stringify(paymentData));
      }
    } catch (error) {
      console.error('授权支付流程失败:', error);
      hidePaymentLoading();
      this.handlePaymentError(error);
    }
  }

  /**
   * 直接处理支付（无授权码）
   */
  async processDirectPayment() {
    try {
      this.setStatus(PaymentStatus.PROCESSING);
      
      // 第一步：获取微信授权
      showPaymentLoading('获取微信授权...');
      console.log('开始获取微信授权:', this.contractNumber);
      
      // 检查是否已经有授权码在URL中
      const authResult = detectWechatAuthCallback();
      if (authResult.hasAuthCallback) {
        console.log('检测到URL中已有授权码，直接处理授权回调');
        hidePaymentLoading();
        await this.handleAuthCallback(authResult);
        return;
      }
      
      const authData = await getWechatAuth(this.contractNumber);
      console.log('获取到授权数据:', authData);
      
      if (authData.authUrl && !this.isHandlingCallback) {
        // 需要跳转到微信授权页面
        hidePaymentLoading();
        this.redirectToAuth(authData.authUrl);
        return;
      }
      
      // 第二步：创建支付订单
      showPaymentLoading('创建支付订单...');
      console.log('开始创建支付订单');
      
      const paymentData = await createPaymentOrder({
        contractId: this.contractData.id,
        amount: this.contractData.payAmount,
        contractNumber: this.contractNumber,
        paymentMethod: 'wechat'
      });

      hidePaymentLoading();
      console.log('支付订单创建完成:', paymentData);

      if (paymentData.auth_url && !this.isHandlingCallback) {
        // 仍然需要授权，缓存支付参数并跳转
        console.log('支付订单返回授权URL，需要重新授权');
        cachePaymentParams(this.contractNumber, paymentData);
        this.redirectToAuth(paymentData.auth_url);
      } else if (paymentData.auth_url && this.isHandlingCallback) {
        // 在处理授权回调时仍然需要授权，说明授权可能失败
        throw new Error('授权验证失败，请重新尝试');
      } else if (paymentData.wechat_pay_params && paymentData.payment_type) {
        // 直接支付
        console.log('开始调起微信支付');
        const result = await callWechatPay(
          paymentData.wechat_pay_params,
          paymentData.payment_type
        );
        this.handlePaymentSuccess(result);
      } else {
        throw new Error('支付参数不完整');
      }
    } catch (error) {
      console.error('支付流程失败:', error);
      hidePaymentLoading();
      this.handlePaymentError(error);
    }
  }

  /**
   * 跳转到授权页面
   * @param {string} authUrl - 授权URL
   */
  redirectToAuth(authUrl) {
    console.log('跳转到微信授权页面:', authUrl);
    
    // 在处理授权回调期间，禁止再次跳转授权
    if (this.isHandlingCallback) {
      console.log('正在处理授权回调，禁止再次跳转授权');
      return;
    }
    
    uni.showModal({
      title: '微信授权',
      content: '为了完成支付，需要获取您的微信授权。点击"去授权"将跳转到微信授权页面，授权完成后会自动返回并完成支付。',
      confirmText: '去授权',
      cancelText: '取消',
      success: (res) => {
        if (res.confirm) {
          console.log('用户确认授权，跳转到:', authUrl);
          this.setStatus(PaymentStatus.AUTHORIZING);
          
          // 显示授权跳转提示
          uni.showToast({
            title: '正在跳转授权...',
            icon: 'loading',
            duration: 2000
          });
          
          // 延迟跳转，让用户看到提示
          setTimeout(() => {
            window.location.href = authUrl;
          }, 500);
        } else {
          console.log('用户取消授权');
          this.setStatus(PaymentStatus.CANCELLED);
          clearCachedPaymentParams(this.contractNumber);
          
          uni.showToast({
            title: '支付已取消',
            icon: 'none',
            duration: 2000
          });
        }
      }
    });
  }

  /**
   * 开始支付流程
   * @param {Object} options - 支付选项
   */
  async startPayment(options = {}) {
    try {
      console.log('开始支付流程:', this.contractNumber);
      
      // 防止在处理授权回调时重新拉起支付
      if (this.isHandlingCallback) {
        console.log('正在处理授权回调，跳过重复支付请求');
        return;
      }
      
      // 防止重复支付
      if (this.status === PaymentStatus.PROCESSING || this.status === PaymentStatus.AUTHORIZING) {
        console.log('支付正在进行中，跳过重复请求');
        return;
      }
      
      // 检查支付环境
      const envCheck = checkWechatPayEnvironment();
      if (!envCheck.isValid) {
        throw new Error(envCheck.error === PaymentError.NOT_IN_WECHAT ? '请在微信中打开' : '微信支付环境不可用');
      }

      // 检查登录状态
      const token = uni.getStorageSync('token');
      if (!token) {
        const shouldLogin = await this.showLoginModal();
        if (shouldLogin) {
          uni.navigateTo({ url: '/pages/login/index' });
        }
        return;
      }

      // 显示支付开始提示
      uni.showToast({
        title: '正在准备支付...',
        icon: 'loading',
        duration: 1500
      });

      // 检查是否有缓存的支付参数
      const cachedParams = getCachedPaymentParams(this.contractNumber);
      if (cachedParams && cachedParams.wechat_pay_params) {
        console.log('使用缓存的支付参数');
        await this.processPaymentWithCachedParams(cachedParams);
      } else {
        console.log('创建新的支付订单');
        await this.processDirectPayment();
      }
    } catch (error) {
      console.error('支付流程失败:', error);
      this.handlePaymentError(error);
    }
  }

  /**
   * 显示登录模态框
   * @returns {Promise<boolean>}
   */
  showLoginModal() {
    return new Promise((resolve) => {
      uni.showModal({
        title: '提示',
        content: '您还未登录，是否前往登录？',
        success: (res) => {
          resolve(res.confirm);
        }
      });
    });
  }

  /**
   * 处理支付成功
   * @param {Object} result - 支付结果
   */
  handlePaymentSuccess(result) {
    console.log('支付成功:', result);
    this.setStatus(PaymentStatus.SUCCESS);
    
    // 清理缓存的支付参数
    clearCachedPaymentParams(this.contractNumber);
    
    // 清理URL中的授权参数
    this.cleanupAuthParams();
    
    showPaymentSuccess(() => {
      console.log('执行支付成功回调');
      this.callbacks.onSuccess(result);
      // 默认行为：返回上一页
      uni.navigateBack();
    });
  }

  /**
   * 处理支付错误
   * @param {Error} error - 错误对象
   */
  handlePaymentError(error) {
    console.error('支付处理失败:', error);
    // 只在非授权回调处理期间清理URL参数
    if (!this.isHandlingCallback) {
      this.cleanupAuthParams();
    }
    if (error.code === PaymentStatus.CANCELLED) {
      this.setStatus(PaymentStatus.CANCELLED);
      this.callbacks.onCancel(error);
    } else {
      this.setStatus(PaymentStatus.FAILED);
      this.callbacks.onError(error);
      
      // 如果是授权相关错误且不在处理授权回调期间，清理缓存的支付参数
      if (error.message && error.message.includes('授权') && !this.isHandlingCallback) {
        clearCachedPaymentParams(this.contractNumber);
      }
    }
    
    handlePaymentError(error);
  }

  /**
   * 更新合同数据
   * @param {Object} contractData - 新的合同数据
   */
  updateContractData(contractData) {
    this.contractData = contractData;
  }

  /**
   * 获取当前状态
   * @returns {string}
   */
  getStatus() {
    return this.status;
  }

  /**
   * 重置状态
   */
  reset() {
    this.setStatus(PaymentStatus.IDLE);
    clearCachedPaymentParams(this.contractNumber);
  }

  /**
   * 销毁管理器
   */
  destroy() {
    this.reset();
    this.callbacks = {};
    this.contractData = null;
    this.contractNumber = null;
  }
  
  /**
   * 检查授权码是否有效
   * @param {string} authCode - 授权码
   * @returns {boolean} 是否有效
   */
  isAuthCodeValid(authCode) {
    // 授权码通常应该有一定长度且不为空
    return authCode && typeof authCode === 'string' && authCode.length > 10;
  }
}